package com.example.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.iam.entity.IamUser;
import com.diboot.iam.util.IamSecurityUtils;
import com.example.demo.dto.ProductionOrderMaterialOne;
import com.example.demo.entity.ProcurementOrderItem;
import com.example.demo.entity.ProcurementStock;
import com.example.demo.entity.ProductionMaterialUsage;
import com.example.demo.service.ProcurementOrderItemService;
import com.example.demo.service.ProcurementStockService;
import com.example.demo.service.ProductionMaterialUsageService;
import com.example.demo.vo.ProcurementStockDetailVO;
import com.example.demo.vo.ProductionOrderMaterialVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.diboot.core.vo.*;
import com.diboot.iam.annotation.OperationCons;
import com.diboot.iam.annotation.BindPermission;
import com.diboot.iam.annotation.Log;
import com.example.demo.entity.ProductionOrderMaterial;
import com.example.demo.dto.ProductionOrderMaterialDTO;
import com.example.demo.vo.ProductionOrderMaterialListVO;
import com.example.demo.vo.ProductionOrderMaterialDetailVO;
import com.example.demo.service.ProductionOrderMaterialService;
import com.example.demo.controller.BaseCustomCrudRestController;
import lombok.extern.slf4j.Slf4j;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 领生产物料 相关Controller
 *
 * @author MyName
 * @version 1.0
 * @date 2024-03-19
 * Copyright © MyCompany
 */
@RestController
@RequestMapping("/productionOrderMaterial")
@BindPermission(name = "领生产物料")
@Slf4j
public class ProductionOrderMaterialController extends BaseCustomCrudRestController<ProductionOrderMaterial> {

    @Autowired
    private ProductionOrderMaterialService productionOrderMaterialService;
    @Autowired
    private ProductionMaterialUsageService productionMaterialUsageService;
    @Autowired
    private ProcurementOrderItemService procurementOrderItemService;
    @Autowired
    private ProcurementStockService procurementStockService;
    /**
     * 查询ViewObject的分页数据
     * <p>
     * url请求参数示例: /list?field=abc&pageIndex=1&orderBy=abc:DESC
     * </p>
     *
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_LIST)
    @BindPermission(name = OperationCons.LABEL_LIST, code = OperationCons.CODE_READ)
    @GetMapping("/list")
    public JsonResult<List<ProductionOrderMaterialListVO>> getViewObjectListMapping(ProductionOrderMaterialDTO queryDto, Pagination pagination) throws Exception {
        return super.getViewObjectList(queryDto, pagination, ProductionOrderMaterialListVO.class);
    }

  @Log(operation = OperationCons.LABEL_LIST)
  @BindPermission(name = OperationCons.LABEL_LIST, code = OperationCons.CODE_READ)
  @GetMapping("/procurementOrderItem")
  public JsonResult<List<ProcurementOrderItem>> keyvalue(ProductionOrderMaterialDTO queryDto, Pagination pagination) throws Exception {
    IamUser iamUser = IamSecurityUtils.getCurrentUser();
    QueryWrapper<ProductionOrderMaterial> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda().eq(ProductionOrderMaterial::getIamUserId, iamUser.getId());
    queryWrapper.select("Distinct procurement_order_item_id");
    List<Long> idList = productionOrderMaterialService.getEntityList(queryWrapper).stream().map(ProductionOrderMaterial::getProcurementOrderItemId).collect(Collectors.toList());
    LambdaQueryWrapper<ProcurementOrderItem> queryWrapper1 = new LambdaQueryWrapper();
    queryWrapper1.in(ProcurementOrderItem::getId, idList);
    return JsonResult.OK(procurementOrderItemService.getEntityList(queryWrapper1));
  }
    /**
     * 根据资源id查询ViewObject
     *
     * @param id ID
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_DETAIL)
    @BindPermission(name = OperationCons.LABEL_DETAIL, code = OperationCons.CODE_READ)
    @GetMapping("/{id}")
    public JsonResult getViewObjectMapping(@PathVariable("id") Long id) throws Exception {
        return super.getViewObject(id, ProductionOrderMaterialDetailVO.class);
    }

    /**
     * 创建资源对象
     *
     * @param entity
     * @return JsonResult
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @PostMapping("/")
    public JsonResult<?> createEntityMapping(@Valid @RequestBody ProductionOrderMaterialVO entity) throws Exception {
        LambdaQueryWrapper<ProcurementStock> queryWrapper1 = new LambdaQueryWrapper<ProcurementStock>();
        queryWrapper1.eq(ProcurementStock::getProcurementOrderItemId, entity.getProcurementOrderItemId());
        queryWrapper1.eq(ProcurementStock::getStoreroomId, entity.getStoreroomId());
        queryWrapper1.eq(ProcurementStock::getStatus, "1");
        ProcurementStock procurementStock =  procurementStockService.getViewObject(queryWrapper1, ProcurementStock.class);
        if(procurementStock.getQuantity().subtract(entity.getQuantity()).compareTo(BigDecimal.ZERO) > 0) {
          procurementStock.setQuantity(procurementStock.getQuantity().subtract(entity.getQuantity()));
          procurementStockService.updateEntity(procurementStock);
        } else if (procurementStock.getQuantity().subtract(entity.getQuantity()).compareTo(BigDecimal.ZERO) == 0) {
          procurementStock.setQuantity(procurementStock.getQuantity().subtract(entity.getQuantity()));
          procurementStock.setStatus("2");
          procurementStockService.updateEntity(procurementStock);
        } else {
          return JsonResult.FAIL_OPERATION("库存不足");
        }
        return super.createEntity(entity);
    }

    @Log(operation = OperationCons.LABEL_CREATE)
    @BindPermission(name = OperationCons.LABEL_CREATE, code = OperationCons.CODE_WRITE)
    @PostMapping("/one")
    public JsonResult<?> one(@Valid @RequestBody ProductionOrderMaterialOne productionOrderMaterialOne) throws Exception {
      List<ProcurementStock> procurementStockList = new ArrayList<>();
      LambdaQueryWrapper<ProductionMaterialUsage> queryWrapper = new LambdaQueryWrapper<>();
      queryWrapper.eq(ProductionMaterialUsage::getDays, productionOrderMaterialOne.getDays());
      queryWrapper.eq(ProductionMaterialUsage::getIamUserId, productionOrderMaterialOne.getIamUserId());
      queryWrapper.eq(ProductionMaterialUsage::getStatus, "1");
      List<ProductionMaterialUsage> productionMaterialUsageList = productionMaterialUsageService.getEntityList(queryWrapper);
      for(ProductionMaterialUsage productionMaterialUsage : productionMaterialUsageList) {
        LambdaQueryWrapper<ProcurementStock> queryWrapper1 = new LambdaQueryWrapper<ProcurementStock>();
        queryWrapper1.eq(ProcurementStock::getProcurementOrderItemId, productionMaterialUsage.getProcurementOrderItemId());
        queryWrapper1.eq(ProcurementStock::getStoreroomId, productionOrderMaterialOne.getStoreroomId());
        queryWrapper1.eq(ProcurementStock::getStatus, "1");
        ProcurementStock procurementStock =  procurementStockService.getViewObject(queryWrapper1, ProcurementStock.class);
        if(procurementStock.getQuantity().subtract(productionMaterialUsage.getQuantity()).compareTo(BigDecimal.ZERO) >= 0) {
          procurementStock.setQuantity(procurementStock.getQuantity().subtract(productionMaterialUsage.getQuantity()));
          procurementStockList.add(procurementStock);
        } else if(procurementStock.getQuantity().subtract(productionMaterialUsage.getQuantity()).compareTo(BigDecimal.ZERO) == 0) {
          procurementStock.setQuantity(procurementStock.getQuantity().subtract(productionMaterialUsage.getQuantity()));
          procurementStock.setStatus("2");
          procurementStockList.add(procurementStock);
        } else {
          return JsonResult.FAIL_OPERATION("库存不足");
        }
      }
      procurementStockService.updateEntities(procurementStockList);

      List<ProductionOrderMaterial> productionOrderMaterialList = new ArrayList<>();
      for(ProductionMaterialUsage productionMaterialUsage : productionMaterialUsageList) {
        ProductionOrderMaterial productionOrderMaterial = new ProductionOrderMaterial();
        productionOrderMaterial.setProcurementOrderItemId(productionMaterialUsage.getProcurementOrderItemId());
        productionOrderMaterial.setIamUserId(productionMaterialUsage.getIamUserId());
        productionOrderMaterial.setQuantity(productionMaterialUsage.getQuantity());
        productionOrderMaterial.setProductionMaterialUsageId(productionMaterialUsage.getId());
        productionOrderMaterial.setUnitId(productionMaterialUsage.getUnitId());
        productionOrderMaterialList.add(productionOrderMaterial);
        productionMaterialUsage.setStatus("2");
      }
      productionMaterialUsageService.updateEntities(productionMaterialUsageList);
       productionOrderMaterialService.createEntities(productionOrderMaterialList);
      return JsonResult.OK();
    }
    /**
     * 根据ID更新资源对象
     *
     * @param entity
     * @return JsonResult
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_UPDATE)
    @BindPermission(name = OperationCons.LABEL_UPDATE, code = OperationCons.CODE_WRITE)
    @PutMapping("/{id}")
    public JsonResult<?> updateEntityMapping(@PathVariable("id") Long id, @Valid @RequestBody ProductionOrderMaterial entity) throws Exception {
        return super.updateEntity(id, entity);
    }

    /**
     * 根据id删除资源对象
     *
     * @param id
     * @return
     * @throws Exception
     */
    @Log(operation = OperationCons.LABEL_DELETE)
    @BindPermission(name = OperationCons.LABEL_DELETE, code = OperationCons.CODE_WRITE)
    @DeleteMapping("/{id}")
    public JsonResult<?> deleteEntityMapping(@PathVariable("id") Long id) throws Exception {
        return super.deleteEntity(id);
    }
}
